﻿using System;
using System.Collections.Generic;
using System.Xml;
using Assist;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using YJKOpeningCommon.OpeningEX;
using YJKOpeningCommon.OpeningProfile;
using YJKOpeningCommon.Public;

namespace YJKOpeningCommon.DbOpening
{
	public class DbCircleBeamOpening : DbNativeOpening
	{
		private static XYZ getTransformX(FamilyInstance beam)
		{
			LocationCurve locationCurve = beam.Location as LocationCurve;
			Line line = locationCurve.Curve as Line;
			if (line == null)
			{
				return null;
			}
			return (line.GetEndPoint(1) - line.GetEndPoint(0)).Normalize();
		}

		public override bool CreateOpeningFamilyInstance(ViewScene ViewScene, out Element elem3D, out Element elem2D)
		{
			elem2D = null;
			View viewOpening2D = ViewScene.m_viewOpening2D;
			if (viewOpening2D == null)
			{
				elem3D = null;
				return false;
			}
			Document document = viewOpening2D.Document;
			OpeningXData openingXData = new OpeningXData();
			base.GetOpeningXDataBase(ref openingXData);
			Transaction transaction = new Transaction(document, "CreateOpeningFamilyInstance");
			try
			{
				transaction.Start();
				Element element = document.GetElement(this.m_strHostUniqueId);
				FamilyInstance beam = element as FamilyInstance;
				OpeningProfileCircle openingProfileCircle = this.m_profile as OpeningProfileCircle;
				double num = openingProfileCircle.m_dExtendDist + openingProfileCircle.m_dCutDiameter / 2.0;
				Arc arc = document.CreatYJKArc(openingProfileCircle.m_position, num, 0.0, Math.PI*2, DbCircleBeamOpening.getTransformX(beam), XYZ.BasisZ.Normalize());
				CurveArray curveArray = new CurveArray();
				curveArray.Append(arc);
                Opening opening = document.Create.NewOpening(element, curveArray, (Autodesk.Revit.Creation.eRefFace)4);
				openingXData.m_dHeight = (openingXData.m_dWidth = num * 2.0);
				openingXData.m_eOpeningProfile = 0;
				openingXData.m_dMaxZ = openingProfileCircle.m_position.Z + num / 2.0;
				openingXData.m_dMinZ = openingProfileCircle.m_position.Z - num / 2.0;
				openingXData.WriteOpeningXData(opening);
				transaction.Commit();
				elem3D = opening;
			}
			catch (Exception)
			{
				elem3D = null;
				transaction.RollBack();
				return false;
			}
			return true;
		}

		public override bool IsNeedCreateFamily()
		{
			return false;
		}

		public override bool CreateOpeningPreviewInstance(out Element elemPreview, PreViewScene preViewScene)
		{
			elemPreview = null;
			OpeningProfileCircle openingProfileCircle = this.m_profile as OpeningProfileCircle;
			XYZ position = openingProfileCircle.m_position;
			XYZ directionProfile = openingProfileCircle.m_directionProfile;
			double num = 1.0;
			double radius = openingProfileCircle.m_dCutDiameter * num / 2.0;
			Transaction transaction = new Transaction(preViewScene.m_doc, "CreateModelGroup");
			try
			{
				XYZ origin = position + directionProfile * (this.m_dHostWidth / 2.0 + preViewScene.m_offset);
				Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(directionProfile, origin);
				if (plane == null)
				{
					return false;
				}
				List<ElementId> list = new List<ElementId>();
				if (!CommonInterface.CreateModelCurve(radius, preViewScene.m_doc, plane, ref list, preViewScene.m_modelLineElemId))
				{
					return false;
				}
				XYZ origin2 = position + directionProfile.Negate() * (this.m_dHostWidth / 2.0 + preViewScene.m_offset);
				plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(directionProfile.Negate(), origin2);
				if (plane == null)
				{
					return false;
				}
				if (!CommonInterface.CreateModelCurve(radius, preViewScene.m_doc, plane, ref list, preViewScene.m_modelLineElemId))
				{
					return false;
				}
				transaction.Start();
				elemPreview = preViewScene.m_doc.Create.NewGroup(list);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
				return false;
			}
			return true;
		}

		public override void AddSharedParameters(Element elem)
		{
		}

		public override bool Equals(object obj)
		{
			return base.Equals(obj);
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		public override bool Export2XmlNode(XmlElement xmlNode)
		{
			bool result;
			try
			{
				if (!base.Export2XmlNode(xmlNode))
				{
					result = false;
				}
				else
				{
					result = true;
				}
			}
			catch
			{
				xmlNode = null;
				result = false;
			}
			return result;
		}

		public override bool ImportByXmlNode(XmlNode xmlNode)
		{
			try
			{
				if (!base.ImportByXmlNode(xmlNode))
				{
					return false;
				}
			}
			catch
			{
				return false;
			}
			return true;
		}
	}
}
